using System;
using System.Linq;
using System.Web.Mvc;
using OurWedding1.Models;

namespace OurWedding1.Controllers
{
    [Authorize]
    public class TasksController : BaseController
    {
        private readonly IGuestRepository _guestRepository;
        private readonly IExpenseRepository _expenseRepository;
        private readonly ITaskRepository _taskRepository;

        // If you are using Dependency Injection, you can delete the following constructor
        public TasksController()
            : this(new GuestRepository(), new ExpenseRepository(), new TaskRepository())
        {
        }

        public TasksController(IGuestRepository guestRepository, IExpenseRepository expenseRepository, ITaskRepository taskRepository)
        {
            _guestRepository = guestRepository;
            _expenseRepository = expenseRepository;
            _taskRepository = taskRepository;
        }

        //
        // GET: /Tasks/



        public ActionResult Index()
        {

            if (!SelectedWeddingId.HasValue)
            {
                return RedirectToAction("Index", "Weddings");
            }

            var model = _taskRepository.AllIncluding(task => task.Guest, expense => expense.Expens);
            model = model.Where(t => t.Expens.WeddingId == SelectedWeddingId.Value); //TODO:Do some test
            model = model.OrderBy(t => t.Deadline).ThenBy(t => t.Expens);
            return View(new TasksIndexViewModel(model));
        }

        public ActionResult IndexByExpense(int id)
        {
            if (!SelectedWeddingId.HasValue)
            {
                return Content("");
            }

            var model = _taskRepository.AllIncluding(task => task.Guest, expense => expense.Expens);
            model = model.Where(t => t.Expens.WeddingId == SelectedWeddingId.Value).Where(t => t.ExpenseId == id); //TODO:Do some test
            model = model.OrderBy(t => t.Deadline);
            return PartialView("_IndexByExpense", model);
        }

        //
        // GET: /Tasks/Details/5

        public ViewResult Details(int id)
        {
            return View(_taskRepository.Find(id));
        }

        
        //GET /Tasks/CreateByExpense id=ExpenseId
        public ActionResult CreateByExpense(int id)
        {
            var expense = _expenseRepository.Find(id);
            if (!SelectedWeddingId.HasValue || expense == null)
            {
                return Content("");
            }
            ViewBag.PossibleGuests = _guestRepository.All.Where(d => d.GuestGroup.WeddingId == SelectedWeddingId.Value).Where(g => g.GuestFunction != null).OrderBy(g => g.LastName);
            var model = new Task {ExpenseId = expense.ExpenseId};
            return PartialView("_CreateByExpense", model);
        }

        [HttpPost]
        public ActionResult CreateByExpense(int id, Task model)
        {
            if (ModelState.IsValid)
            {
                // validation of the modal view model succeeded =>
                // we return a JSON result containing some precalculated value

                _taskRepository.InsertOrUpdate(model);
                bool succeded;
                try
                {
                    _taskRepository.Save();
                    succeded = true;
                }
                catch (Exception)
                {
                    succeded = false;
                }

                if (succeded)
                {
                    return Json(new
                    {
                        value = "K!"
                    });
                }
                ModelState.AddModelError("a", Resources.ErrorOcured);

            }
            // Validation failed => we need to redisplay the modal form
            // and give the user the possibility to fix his errors
            var selectedWedding = SelectedWeddingId;
            ViewBag.PossibleGuests = _guestRepository.All.Where(d => d.GuestGroup.WeddingId == selectedWedding.Value).Where(g => g.GuestFunction != null).OrderBy(g => g.LastName);
            return PartialView("_CreateByExpense", model);
        }

        //
        // GET: /Tasks/Create

        public ActionResult Create()
        {
            if (!SelectedWeddingId.HasValue)
            {
                return RedirectToAction("Index", "Weddings");
            }
            ViewBag.PossibleGuests = _guestRepository.All.Where(d => d.GuestGroup.WeddingId == SelectedWeddingId.Value).Where(g => g.GuestFunction != null).OrderBy(g => g.LastName);
            ViewBag.PossibleExpenses = _expenseRepository.All.OrderBy(e => e.Name);
            return View();
        }

        //
        // POST: /Tasks/Create

        [HttpPost]
        public ActionResult Create(Task task)
        {
            if (ModelState.IsValid)
            {
                _taskRepository.InsertOrUpdate(task);
                _taskRepository.Save();
                return RedirectToAction("Index");
            }
            ViewBag.PossibleGuests = _guestRepository.All.Where(d => d.GuestGroup.WeddingId == SelectedWeddingId.Value).Where(g => g.GuestFunction != null).OrderBy(g => g.LastName);
            ViewBag.PossibleExpenses = _expenseRepository.All.OrderBy(e => e.Name);
            return View();
        }

        //
        // GET: /Tasks/Edit/5

        public ActionResult Edit(int id)
        {
            ViewBag.PossibleGuests = _guestRepository.All.Where(d => d.GuestGroup.WeddingId == SelectedWeddingId.Value).Where(g => g.GuestFunction != null).OrderBy(g => g.LastName);
            ViewBag.PossibleExpenses = _expenseRepository.All.OrderBy(e => e.Name);
            return View(_taskRepository.Find(id));
        }

        //
        // POST: /Tasks/Edit/5

        [HttpPost]
        public ActionResult Edit(Task task)
        {
            if (ModelState.IsValid)
            {
                _taskRepository.InsertOrUpdate(task);
                _taskRepository.Save();
                return RedirectToAction("Index");
            }
            ViewBag.PossibleGuests = _guestRepository.All.Where(d => d.GuestGroup.WeddingId == SelectedWeddingId.Value).Where(g => g.GuestFunction != null).OrderBy(g => g.LastName);
            ViewBag.PossibleExpenses = _expenseRepository.All.OrderBy(e => e.Name);
            return View();
        }

        public ActionResult EditByExpense(int id)
        {
            var model = _taskRepository.Find(id);
            if (!SelectedWeddingId.HasValue || model == null)
            {
                return Content("");
            }
            ViewBag.PossibleGuests = _guestRepository.All.Where(d => d.GuestGroup.WeddingId == SelectedWeddingId.Value).Where(g => g.GuestFunction != null).OrderBy(g => g.LastName);
            return PartialView("_EditByExpense", model);
        }

        [HttpPost]
        public ActionResult EditByExpense(Task model)
        {
            if (ModelState.IsValid)
            {
                // validation of the modal view model succeeded =>
                // we return a JSON result containing some precalculated value
                _taskRepository.InsertOrUpdate(model);
                bool succeded;
                try
                {
                    _taskRepository.Save();
                    succeded = true;
                }
                catch (Exception)
                {
                    succeded = false;
                }

                if (succeded)
                {
                    return Json(new
                    {
                        value = "K!"
                    });
                }
                ModelState.AddModelError("a", Resources.ErrorOcured);

            }
            // Validation failed => we need to redisplay the modal form
            // and give the user the possibility to fix his errors
            var selectedWedding = SelectedWeddingId;
            ViewBag.PossibleGuests = _guestRepository.All.Where(d => d.GuestGroup.WeddingId == selectedWedding.Value).Where(g => g.GuestFunction != null).OrderBy(g => g.LastName);
            return PartialView("_EditByExpense", model);
        }

        //
        // GET: /Tasks/Delete/5

        public ActionResult Delete(int id)
        {
            if (!SelectedWeddingId.HasValue)
            {
                return RedirectToAction("Index", "Weddings");
            }
            var model = _taskRepository.Find(id);
            if (model == null)
            {
                return HttpNotFound();
            }
            if (model.Expens.WeddingId != SelectedWeddingId)
            {
                return RedirectToAction("Index", "Weddings");
            }
            return View(model);
        }

        //
        // POST: /Tasks/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            _taskRepository.Delete(id);
            _taskRepository.Save();

            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult DeleteAjax(int id)
        {
            var model = _taskRepository.Find(id); //TODO:Security
            if (!SelectedWeddingId.HasValue || model == null)
            {
                return Json(new
                {
                    value = "nok"
                });
            }
            _taskRepository.Delete(id);
            bool succeded;
            try
            {
                _taskRepository.Save();
                succeded = true;
            }
            catch (Exception)
            {
                succeded = false;
            }

            if (succeded)
            {
                return Json(new
                            {
                                value = "ok"
                            });
            }
            return Json(new
                {
                    value = "nok"
                });
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _guestRepository.Dispose();
                _expenseRepository.Dispose();
                _taskRepository.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

